package com.chuangke.sinotrukbudget.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;

import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chuangke.common.utils.DateUtils;
import com.chuangke.flow.domain.FlowAuditResult;
import com.chuangke.framework.model.Record;
import com.chuangke.sinotrukbudget.model.BudgetAccount;
import com.chuangke.sinotrukbudget.model.BudgetBpcPlan;

public class BudgetUtil {

    private static final char blankChar = (char) 127;

    /**
     * @param queryWrapper
     * @只有审批线索为"INPUT_E3","INPUT"和T_FLOW为F_NONE的参与流程 INPUT_E3为费用业务预算，INPUT为业务预算，T_FLOW不为F_NONE的存着实际的预算值
     * @给科目预算查询增加限定死的查询条件 值查询审批线索为"INPUT_E3","INPUT"的，正常接收的数据也只有这两个
     * @T_FLOW为F_NONE
     */
    public static void appendRestrictQueryWrapperAudit(QueryWrapper<BudgetBpcPlan> queryWrapper) {
		/*
		  只有审批线索为"INPUT_E3","INPUT"和T_FLOW不为F_NONE的参与流程
		  INPUT_E3为费用业务预算，INPUT为业务预算，T_FLOW不为F_NONE的存着实际的预算值 给科目预算查询增加限定死的查询条件
		  值查询审批线索为"INPUT_E3","INPUT"的，正常接收的数据也只有这两个。 T_FLOW不为F_NONE
		 */
        queryWrapper.lambda().in(BudgetBpcPlan::gettAudit, Arrays.asList("INPUT_E3", "INPUT"))
                .ne(BudgetBpcPlan::gettFlow, "F_NONE").eq(BudgetBpcPlan::gettFlow1, "F1_NONE")
                .eq(BudgetBpcPlan::gettFlow4, "F4_NONE");
    }

    /**
     * 是否参与流程
     */
    public static boolean isInFlow(BudgetBpcPlan bbp) {
        List<String> auditList = Arrays.asList("INPUT_E3", "INPUT");
        return auditList.contains(bbp.gettAudit()) && !"F_NONE".equals(bbp.gettFlow())
                && BudgetAccount.ACCOUNT_TYPE_CW.equals(bbp.getAccountType())
                && "F1_NONE".equals(bbp.gettFlow1()) && "F4_NONE".equals(bbp.gettFlow4());		
                		
    }

    /**
     * 流程审批结果不符合预算审批，重新组织审批结果
     *
     * @param far
     * @param bbpList
     * @return
     */
    public static FlowAuditResult handleFlowAuditResult(FlowAuditResult far, List<BudgetBpcPlan> bbpList) {
        FlowAuditResult result = new FlowAuditResult();

        Map<String, BudgetBpcPlan> bbpMap = bbpList.stream().collect(Collectors.toMap(BudgetBpcPlan::getId, a -> a));

        List<BudgetBpcPlan> successBbpList = bbpList.stream()
                .filter(bbp -> far.getSuccessOrderIdList().contains(bbp.getId())).collect(Collectors.toList());
        List<BudgetBpcPlan> failBbpList = bbpList.stream().filter(bbp -> far.getFailOrderIdList().contains(bbp.getId()))
                .collect(Collectors.toList());

        result.setSuccessCount((int) successBbpList.stream().map(BudgetUtil::getFlowUniqueKey).distinct().count());
        result.setFailCount((int) failBbpList.stream().map(BudgetUtil::getFlowUniqueKey).distinct().count());

        List<String> fialMsgList = new ArrayList<>();

        far.getFailMsgList().forEach(msg -> {
            String[] msgarr = msg.split("\\[|\\]");
            String newMsg = msgarr.length == 3
                    ? String.format("%s%s", getFlowDescriptions(bbpMap.get(msgarr[1])), msgarr[2])
                    : msg;
            fialMsgList.add(newMsg);

        });
        result.setFailMsgList(fialMsgList.stream().distinct().collect(Collectors.toList()));
        return result;
    }

    private static String getFlowDescriptions(BudgetBpcPlan bbp) {
        return String.format("公司[%s]下的科目[%s]", bbp.gettEntity(), bbp.gettAccount());
    }

    /**
     * 流程唯一key，代表key相同的应该是一个路程（前提条件是数据在一套期间里）
     *
     * @param bbp
     * @return
     */
    public static String getFlowUniqueKey(BudgetBpcPlan bbp) {
        return String.format("%s-%s-%s", bbp.gettEntity(), bbp.gettCategory(), bbp.gettAccount());
    }

    public static List<String> getTimeList(String category, String time) {
        List<String> timeList = new ArrayList<>();
        /*概算获取的是当前期间和下一年；非概算获取的为当前期间*/
        if (category.startsWith("BUD")) {
            String year = time.substring(0, 4);
            String nextYear = DateUtils.nextYear(year);
            timeList.add(time);
            timeList.add(nextYear + ".INP");
        } else {
            timeList.add(time);
        }

        return timeList;
    }

    /**
     * 预算主键列
     *
     * @return
     */
    public static List<String> getUnikeyColumn() {
        return Arrays.asList("T_ENTITY", "T_CATEGORY", "T_AUDIT", "T_ACCOUNT", "T_TIME", "T_FLOW",
                "T_FLOW1", "T_FLOW2", "T_FLOW3", "T_FLOW4", "T_FLOW5", "T_FLOW6", "T_OBJECT");
    }

    /**
     * 获取主键的空值
     *
     * @return
     */
    public static Map<String, String> getUniqueNullValue() {
        Map<String, String> nullMap = new HashMap<>();
        nullMap.put("T_FLOW", "F_NONE");
        nullMap.put("T_FLOW1", "F1_NONE");
        nullMap.put("T_FLOW2", "F2_NONE");
        nullMap.put("T_FLOW3", "F3_NONE");
        nullMap.put("T_FLOW4", "F4_NONE");
        nullMap.put("T_FLOW5", "F5_NONE");
        nullMap.put("T_FLOW6", "F6_NONE");
        nullMap.put("T_OBJECT", "O_NONE");
        return nullMap;
    }

    /**
     * 存储主键：数据库存储的唯一uinique索引
     *
     * @param bbp
     * @return
     */
    public static String getStoreUniqeKey(BudgetBpcPlan bbp) {
        Map<String, String> nullMap = getUniqueNullValue();
        // T_ENTITY;T_CATEGORY;T_AUDIT;T_ACCOUNT;T_TIME;T_FLOW;T_FLOW1;T_FLOW2;T_FLOW3;T_FLOW4;T_FLOW5;T_FLOW6;T_OBJECT
        String entity = bbp.gettEntity().replaceAll(blankChar + "", "").trim();
        String category = bbp.gettCategory();
        String account = bbp.gettAccount().replaceAll(blankChar + "", "").trim();
        String time = bbp.gettTime();
        String audit = bbp.gettAudit();
        String flow = StrUtil.isBlank(bbp.gettFlow()) ? nullMap.get("T_FLOW") : bbp.gettFlow();
        String flow1 = StrUtil.isBlank(bbp.gettFlow1()) ? nullMap.get("T_FLOW1") : bbp.gettFlow1();
        String flow2 = StrUtil.isBlank(bbp.gettFlow2()) ? nullMap.get("T_FLOW2") : bbp.gettFlow2();
        String flow3 = StrUtil.isBlank(bbp.gettFlow3()) ? nullMap.get("T_FLOW3") : bbp.gettFlow3();
        String flow4 = StrUtil.isBlank(bbp.gettFlow4()) ? nullMap.get("T_FLOW4") : bbp.gettFlow4();
        String flow5 = StrUtil.isBlank(bbp.gettFlow5()) ? nullMap.get("T_FLOW5") : bbp.gettFlow5();
        String flow6 = StrUtil.isBlank(bbp.gettFlow6()) ? nullMap.get("T_FLOW6") : bbp.gettFlow6();
        String object = StrUtil.isBlank(bbp.gettObject()) ? nullMap.get("T_OBJECT") : bbp.gettObject();

        return String.format("%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s", entity, category, account, time,
                audit, flow, flow1, flow2, flow3, flow4, flow5, flow6, object);
    }

    public static List<Record> convert(List<BudgetBpcPlan> budgetList) {
        if (CollectionUtils.isEmpty(budgetList)) {
            return new ArrayList<>();
        }

        List<Record> list = new ArrayList<>(budgetList.size());
        Record record = null;
        for (BudgetBpcPlan bbp : budgetList) {
            record = new Record();
            record.put("id", bbp.getId());
            record.put("submitter", bbp.getSubmitter());
            record.put("remark1", bbp.getRemark1());
            record.put("remark2", bbp.getRemark2());
            record.put("remark3", bbp.getRemark3());
            record.put("remark4", bbp.getRemark4());
            record.put("remark5", bbp.getRemark5());
            record.put("remark6", bbp.getRemark6());
            record.put("t_entity", bbp.gettEntity());
            record.put("t_category", bbp.gettCategory());
            record.put("t_audit", bbp.gettAudit());
            record.put("t_account", bbp.gettAccount());
            record.put("t_time", bbp.gettTime());
            record.put("t_flow", bbp.gettFlow());
            record.put("t_flow1", bbp.gettFlow1());
            record.put("t_flow2", bbp.gettFlow2());
            record.put("t_flow3", bbp.gettFlow3());
            record.put("t_flow4", bbp.gettFlow4());
            record.put("t_flow5", bbp.gettFlow5());
            record.put("t_flow6", bbp.gettFlow6());
            record.put("t_object", bbp.gettObject());
            record.put("signdata", bbp.getSigndata());
            record.put("scomment", bbp.getScomment());
            record.put("row_remark1", bbp.getRowRemark1());
            record.put("row_remark2", bbp.getRowRemark2());
            record.put("row_remark3", bbp.getRowRemark3());
            record.put("row_remark4", bbp.getRowRemark4());
            record.put("status", bbp.getStatus());
            record.put("bisType", bbp.getBisType());
            record.put("deptType", bbp.getDeptType());
            record.put("in_uuid", bbp.getInUuid());
            record.put("in_status", bbp.getInStatus());
            record.put("out_uuid", bbp.getOutUuid());
            record.put("out_status", bbp.getOutStatus());

            list.add(record);
        }
        return list;
    }
}
